﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Text;
using System.IO;
using System.Runtime.InteropServices;
using System.Text;
using System.Text.RegularExpressions;
using Assist;
using Autodesk.Revit.DB;
using Autodesk.Revit.UI;
using YArchitech.Revit;
using YJKArch.Utils;

namespace YJKArch.DimensionModule
{
	public class SpecialCharactorDrawingKit
	{
		public double TextHeigth
		{
			get
			{
				return this.m_TextHeight;
			}
		}

		public double TextWidthScale
		{
			get
			{
				return this.m_TextWidthScale;
			}
		}

		public double CharHeightCoefficient
		{
			get
			{
				return this.m_CharHeightCoefficient;
			}
		}

		public double CharWidthCoefficient
		{
			get
			{
				return this.m_CharWidthCoefficient;
			}
		}

		public SpecialCharactorDrawingKit(ExternalCommandData cmdData, string generalTextTypeName)
		{
			this.InitHYFont();
			this.m_Revit = cmdData;
			this.m_GeneralType = this.GetTextNoteTypeByName(this.m_Revit.Application.ActiveUIDocument.Document, generalTextTypeName);
			this.m_TextHeight = this.m_GeneralType.get_Parameter(BuiltInParameter.TEXT_SIZE).AsDouble();
			this.m_TextWidthScale = this.m_GeneralType.get_Parameter(BuiltInParameter.TEXT_WIDTH_SCALE).AsDouble();
			this.m_GeneralType.get_Parameter(BuiltInParameter.LEADER_OFFSET_SHEET).Set(0.0);
			this.m_SpecialType = this.GetTextNoteType("HY_Arial", this.m_TextHeight, this.m_TextWidthScale);
			this.m_SpecialType.get_Parameter(BuiltInParameter.LEADER_OFFSET_SHEET).Set(0.0);
		}

		public SpecialCharactorDrawingKit(ExternalCommandData cmdData, string generalTextTypeName, double textHeigth, double textWidth)
		{
			this.InitHYFont();
			this.m_Revit = cmdData;
			this.m_GeneralType = this.GetTextNoteTypeByName(this.m_Revit.Application.ActiveUIDocument.Document, generalTextTypeName);
			this.m_GeneralType.get_Parameter(BuiltInParameter.TEXT_SIZE).Set(textHeigth);
			this.m_GeneralType.get_Parameter(BuiltInParameter.TEXT_WIDTH_SCALE).Set(textWidth);
			this.m_TextHeight = textHeigth;
			this.m_TextWidthScale = textWidth;
			this.m_GeneralType.get_Parameter(BuiltInParameter.LEADER_OFFSET_SHEET).Set(0.0);
			this.m_SpecialType = this.GetTextNoteType("HY_Arial", this.m_TextHeight, this.m_TextWidthScale);
			this.m_SpecialType.get_Parameter(BuiltInParameter.LEADER_OFFSET_SHEET).Set(0.0);
		}

		[DllImport("kernel32.dll", SetLastError = true)]
		private static extern int WriteProfileString(string lpszSection, string lpszKeyName, string lpszString);

		[DllImport("gdi32")]
		public static extern int AddFontResource(string lpFileName);

		private void InstallFont()
		{
			string str = Environment.GetEnvironmentVariable("WINDIR") + "\\fonts";
			string text = "HY_ARIALUNI_V1.TTF";
			string str2 = "HY Arial Unicode MS v1";
			string text2 = str + "\\" + text;
			if (!File.Exists(text2))
			{
				File.Copy(AssistFunc.GetAppRootPath() + "\\Data\\HY_ARIALUNI_V1.TTF", text2);
				SpecialCharactorDrawingKit.AddFontResource(text2);
				SpecialCharactorDrawingKit.WriteProfileString("fonts", str2 + "(TrueType)", text);
			}
		}

		private void InitHYFont()
		{
			FontFamily[] families = new InstalledFontCollection().Families;
			for (int i = 0; i < families.Length; i++)
			{
				if (families[i].Name.CompareTo("HY Arial Unicode MS v1") == 0)
				{
					return;
				}
			}
			this.InstallFont();
		}

		public List<Element> DrawSingleRowCharactors(XYZ ptBase, string text, SpecialCharactorDrawingKit.TextHorizontalAlignment hAlignment, SpecialCharactorDrawingKit.TextVerticalAlignment vAlignment)
		{
			List<SpecialCharactorAnalyser.CharactorInfo> charactorInfoList = SpecialCharactorAnalyser.SplitString(text);
			return this.DrawSingleRowCharactors(ptBase, charactorInfoList, hAlignment, vAlignment);
		}

		public List<Element> DrawSingleRowCharactors1(XYZ ptBase, string text, SpecialCharactorDrawingKit.TextHorizontalAlignment hAlignment, SpecialCharactorDrawingKit.TextVerticalAlignment vAlignment)
		{
			List<SpecialCharactorAnalyser.CharactorInfo> charactorInfoList = SpecialCharactorAnalyser.SplitString(text);
			return this.DrawSingleRowCharactors(ptBase, charactorInfoList, hAlignment, vAlignment);
		}

		private List<Element> DrawSingleRowCharactors(XYZ ptBase, List<SpecialCharactorAnalyser.CharactorInfo> charactorInfoList, SpecialCharactorDrawingKit.TextHorizontalAlignment hAlignment, SpecialCharactorDrawingKit.TextVerticalAlignment vAlignment)
		{
			Autodesk.Revit.DB.Document document = this.m_Revit.Application.ActiveUIDocument.Document;
			Autodesk.Revit.DB.View activeView = document.ActiveView;
			XYZ baseVec = activeView.RightDirection;
			XYZ upDirection = activeView.UpDirection;
			if (Convert.ToInt32(this.m_Revit.Application.Application.VersionNumber) > 2015)
			{
				baseVec = XYZ.BasisX;
			}
			List<Element> list = new List<Element>();
			double num = this.m_TextHeight * this.m_TextWidthScale * (double)activeView.Scale;
            TextAlignFlags textAlignFlags = (TextAlignFlags)512;
			double num2 = 0.25 * num;
			double num3 = 0.0;
			XYZ xyz = ptBase;
			if (hAlignment == SpecialCharactorDrawingKit.TextHorizontalAlignment.THA_LEFT)
			{
                textAlignFlags |= (TextAlignFlags)64;
				for (int i = 0; i < charactorInfoList.Count; i++)
				{
					SpecialCharactorAnalyser.CharactorInfo charactorInfo = charactorInfoList[i];
					if (charactorInfo.m_Text.CompareTo("") != 0)
					{
						double num4 = (double)SpecialCharactorDrawingKit.GetLength(charactorInfo.m_Text);
						TextNoteType textNoteType = this.m_GeneralType;
						if (charactorInfo.m_Type == SpecialCharactorAnalyser.CharactorType.SpecialCharactor)
						{
							textNoteType = this.m_SpecialType;
							num4 = (double)charactorInfo.m_Text.Length * 1.18;
						}
						xyz += activeView.RightDirection * num3;
						XYZ origin = xyz + activeView.UpDirection * (this.m_TextHeight * (double)activeView.Scale * this.GetTextHScale(textNoteType.Name));
						this.OffsetTextPosByRevitVersion(upDirection, this.m_TextHeight * (double)activeView.Scale, ref origin);
						double lineWidth = this.m_TextHeight * this.m_TextWidthScale * (num4 + 2.0);
						TextNote textNode = document.GetTextNode(activeView, origin, baseVec, upDirection, lineWidth, textAlignFlags, charactorInfo.m_Text);
						num3 = (num + num2) * this.GetTextWScale(textNoteType.Name) * num4;
						textNode.TextNoteType = textNoteType;
						list.Add(textNode);
					}
				}
			}
			else
			{
				if (hAlignment != SpecialCharactorDrawingKit.TextHorizontalAlignment.THA_RIGHT)
				{
					throw new Exception("功能未实现.");
				}
                textAlignFlags |= (TextAlignFlags)256;
				for (int j = charactorInfoList.Count - 1; j >= 0; j--)
				{
					SpecialCharactorAnalyser.CharactorInfo charactorInfo2 = charactorInfoList[j];
					if (charactorInfo2.m_Text.CompareTo("") != 0)
					{
						double num5 = (double)SpecialCharactorDrawingKit.GetLength(charactorInfo2.m_Text);
						TextNoteType textNoteType2 = this.m_GeneralType;
						if (charactorInfo2.m_Type == SpecialCharactorAnalyser.CharactorType.SpecialCharactor)
						{
							textNoteType2 = this.m_SpecialType;
							num5 = (double)charactorInfo2.m_Text.Length * 1.18;
						}
						xyz -= activeView.RightDirection * num3;
						XYZ origin2 = xyz + upDirection * (this.m_TextHeight * (double)activeView.Scale * this.GetTextHScale(textNoteType2.Name));
						this.OffsetTextPosByRevitVersion(upDirection, this.m_TextHeight * (double)activeView.Scale, ref origin2);
						double lineWidth2 = this.m_TextHeight * this.m_TextWidthScale * (num5 + 2.0);
						TextNote textNode2 = document.GetTextNode(activeView, origin2, baseVec, upDirection, lineWidth2, textAlignFlags, charactorInfo2.m_Text);
						num3 = (num + num2) * this.GetTextWScale(textNoteType2.Name) * num5;
						textNode2.TextNoteType = textNoteType2;
						list.Add(textNode2);
					}
				}
			}
			return list;
		}

		public void OffsetTextPosByRevitVersion(XYZ vtTextUp, double dRealTextHeight, ref XYZ ptTextPos)
		{
			double num = 0.0;
			int num2 = Convert.ToInt32(this.m_Revit.Application.Application.VersionNumber);
			if (num2 == 2017)
			{
				num = 0.3;
			}
			else if (num2 == 2018)
			{
				num = 0.2;
			}
			ptTextPos += vtTextUp * num * dRealTextHeight;
		}

		public double GetTextHScale(string sTextStyle)
		{
			if (sTextStyle.Contains("仿宋"))
			{
				return 0.65;
			}
			if (sTextStyle.Contains("宋体"))
			{
				return 0.65;
			}
			if (sTextStyle.Contains("黑体"))
			{
				return 0.65;
			}
			if (sTextStyle.Contains("明细表文本"))
			{
				return 0.65;
			}
			if (sTextStyle.Contains("HY_Arial"))
			{
				return 1.1;
			}
			return 1.0;
		}

		public double GetTextWScale(string sTextStyle)
		{
			if (sTextStyle.Contains("HY_Arial"))
			{
				return 0.7;
			}
			return 0.6;
		}

		public static int GetLength(string str)
		{
			if (str == null || str.Length == 0)
			{
				return 0;
			}
			Encoding encoding = new ASCIIEncoding();
			int num = 0;
			byte[] bytes = encoding.GetBytes(str);
			for (int i = 0; i < bytes.Length; i++)
			{
				if (bytes[i] == 63)
				{
					num += 2;
				}
				else
				{
					num++;
				}
			}
			return num;
		}

		public static List<string> SplitString(string str)
		{
			List<string> list = new List<string>();
			if (str == null)
			{
				return list;
			}
			string[] array = Regex.Split(str, "\r\n");
			for (int i = 0; i < array.Length; i++)
			{
				list.Add(array[i]);
			}
			return list;
		}

		public static string MergeString(List<string> strList)
		{
			string text = strList[0];
			for (int i = 1; i < strList.Count; i++)
			{
				text = text + "\r\n" + strList[i];
			}
			return text;
		}

		private TextNoteType GetTextNoteTypeByName(Autodesk.Revit.DB.Document doc, string name)
		{
			int num = 0;
			TextNoteType textNoteType = null;
			TextNoteType result = null;
			foreach (TextNoteType textNoteType2 in Common.GetTextNoteTypes(doc))
			{
				if (num == 0)
				{
					result = textNoteType2;
					num++;
				}
				if (textNoteType2.Name.ToString().Equals(name))
				{
					textNoteType = textNoteType2;
					break;
				}
			}
			if (textNoteType == null)
			{
				return result;
			}
			return textNoteType;
		}

		private TextNoteType GetTextNoteType(string typeName, double size, double widthScale)
		{
			typeName = string.Concat(new string[]
			{
				typeName,
				"-",
				AssistFunc.feetToMM(size).ToString("F1"),
				"mm-",
				widthScale.ToString("F1")
			});
			List<TextNoteType> list = new List<TextNoteType>();
			foreach (Element element in new FilteredElementCollector(this.m_Revit.Application.ActiveUIDocument.Document).OfClass(typeof(TextNoteType)).ToElements())
			{
				TextNoteType textNoteType = element as TextNoteType;
				if (textNoteType != null)
				{
					if (textNoteType.Name.CompareTo(typeName) == 0)
					{
						textNoteType.get_Parameter(BuiltInParameter.TEXT_FONT).Set("HY Arial Unicode MS v1");
						textNoteType.get_Parameter(BuiltInParameter.TEXT_SIZE).Set(size);
						textNoteType.get_Parameter(BuiltInParameter.TEXT_WIDTH_SCALE).Set(widthScale);
						return textNoteType;
					}
					list.Add(textNoteType);
				}
			}
			if (list.Count < 1)
			{
				return null;
			}
			string text = typeName;
			TextNoteType textNoteType2 = list[0].Duplicate(text) as TextNoteType;
			textNoteType2.get_Parameter(BuiltInParameter.TEXT_FONT).Set("HY Arial Unicode MS v1");
			textNoteType2.get_Parameter(BuiltInParameter.TEXT_SIZE).Set(size);
			textNoteType2.get_Parameter(BuiltInParameter.TEXT_WIDTH_SCALE).Set(widthScale);
			return textNoteType2;
		}

		private ExternalCommandData m_Revit;

		private TextNoteType m_GeneralType;

		private TextNoteType m_SpecialType;

		private double m_TextHeight;

		private double m_TextWidthScale;

		private double m_CharHeightCoefficient = 1.5;

		private double m_CharWidthCoefficient = 1.2;

		public enum TextHorizontalAlignment
		{
			THA_LEFT,
			THA_RIGHT,
			THA_CENTER
		}

		public enum TextVerticalAlignment
		{
			TVA_TOP,
			TVA_BOTTOM,
			TVA_MIDDLE
		}
	}
}
